import threading
import time
import winsound
import logging
from datetime import datetime
from PyQt5.QtCore import QObject, pyqtSignal

logger = logging.getLogger(__name__)


class TradeMonitor(QObject):
    # 定义信号，用于与UI通信
    log_message = pyqtSignal(str, str)  # (message, level)
    new_trade_found = pyqtSignal(dict)  # 交易记录字典
    status_update = pyqtSignal(str)  # 状态更新

    def __init__(self, db_manager, crawler, simulator):
        super().__init__()
        self.db_manager = db_manager
        self.crawler = crawler
        self.simulator = simulator
        self.monitoring_active = False
        self.monitoring_thread = None
        self.interval = 100  # 默认100秒
        self.current_page = 1
        self.monitor_trades = []

        logger.info("交易监控器初始化完成")

    def start_monitoring(self, interval=None):
        """启动监控"""
        if self.monitoring_active:
            logger.warning("监控已在运行中")
            return
        self.interval = interval
        self.monitoring_active = True

        # 创建并启动监控线程
        self.monitoring_thread = threading.Thread(target=self.monitor_loop, daemon=True)
        self.monitoring_thread.start()
        logger.info(f"监控已启动，间隔: {interval}秒")
        self.status_update.emit("监控运行中")

    def stop_monitoring(self):
        """停止监控"""
        if not self.monitoring_active:
            logger.warning("监控没有运行")
            return

        self.monitoring_active = False
        if self.monitoring_thread and self.monitoring_thread.is_alive():
            self.monitoring_thread.join(timeout=5)
        logger.info("监控已停止")
        self.status_update.emit("监控已停止")

    def reset_crawler(self):
        """重置爬虫状态"""
        self.crawler.is_initialized = False
        self.crawler.has_more_pages = True
        self.crawler.page_count = 1
        logger.info("爬虫状态已重置")

    def monitor_loop(self):
        """监控循环"""
        logger.info("监控循环开始")

        while self.monitoring_active:
            try:
                # 重置爬虫状态
                self.reset_crawler()

                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                self.log_message.emit(f"[{timestamp}] 开始监控检查...", "INFO")

                # 初始化爬虫
                if not self.crawler.initialize_crawler():
                    self.log_message.emit("爬虫初始化失败，等待下次尝试", "ERROR")
                    time.sleep(self.interval)
                    continue

                page_num = 1
                has_new_trades = True

                while has_new_trades and self.monitoring_active:
                    # 抓取下一页数据
                    trades = self.crawler.fetch_next_page()

                    # 如果没有数据或者没有更多页面，退出循环
                    if not trades or not self.crawler.has_more_pages:
                        has_new_trades = False
                        continue

                    # 处理当前页的交易记录
                    has_new_trades = self.process_page(page_num, trades)

                    # 如果没有新交易，停止抓取后续页面
                    if not has_new_trades:
                        self.log_message.emit(f"第 {page_num} 页没有新交易，停止抓取后续页面", "INFO")

                    page_num += 1

                # 等待下次检查
                if self.monitoring_active:
                    self.log_message.emit(f"等待 {self.interval} 秒后再次检查...", "INFO")
                    time.sleep(self.interval)
            except Exception as e:
                logger.error(f"监控循环出错: {e}")
                self.log_message.emit(f"监控循环出错: {e}", "ERROR")
                time.sleep(60)  # 出错后等待1分钟

    def process_page(self, page_num, trades):
        """处理一页的交易记录"""
        logger.info(f"处理第 {page_num} 页的交易记录 ({len(trades)} 条)")

        # 保存新记录到数据库
        saved_count = 0
        skipped_count = 0
        has_new_trades = False

        for trade in trades:
            # 确保MasterName字段存在
            if 'MasterName' not in trade or not trade['MasterName']:
                logger.warning(f"跳过无效交易记录: 缺少MasterName")
                continue

            master_name = trade['MasterName']
            master_id = self.db_manager.get_master_id_by_name(master_name)

            if not master_id:
                # 添加新高手
                self.db_manager.add_master(master_name)
                master_id = self.db_manager.get_master_id_by_name(master_name)
                #self.log_message.emit(f"添加新高手: {master_name} (ID: {master_id})", "INFO")

            # 确保所有必要字段都存在
            required_fields = ['StockCode', 'StockName', 'TradeType', 'TradePrice', 'TradeVolume', 'TradeDate']
            if not all(field in trade for field in required_fields):
                logger.warning(f"跳过无效交易记录: 缺少必要字段: {trade}")
                continue

            if self.db_manager.is_duplicate_trade(master_id, trade):
                logger.debug(f"跳过重复交易记录: {master_name} - {trade['StockName']} ({trade['TradeType']})")
                skipped_count += 1
            else:
                self.db_manager.add_trade(
                    master_id,
                    trade['StockCode'],
                    trade['StockName'],
                    trade['TradeType'],
                    trade['TradePrice'],
                    trade['TradeVolume'],
                    trade['TradeDate']
                )
                self.db_manager.update_master_last_update(master_id, trade['TradeDate'])
                saved_count += 1
                has_new_trades = True

        self.log_message.emit(f"第 {page_num} 页: 保存了 {saved_count} 条新交易记录，跳过了 {skipped_count} 条记录",
                              "INFO")

        # 如果有新记录，尝试跟单
        if has_new_trades:
            self.process_followed_trades(trades)

        return has_new_trades

    def process_followed_trades(self, trades):
        """处理跟踪高手的交易"""
        # 获取跟踪中的高手
        followed_masters = self.db_manager.get_followed_masters()
        followed_ids = [m['MasterID'] for m in followed_masters]

        # 筛选跟踪高手的新交易
        monitored_trades = []
        for t in trades:
            # 确保MasterName字段存在
            if 'MasterName' not in t or not t.get('MasterName'):
                logger.warning(f"交易记录缺少MasterName字段")
                continue

            # 获取高手ID
            master_id = self.db_manager.get_master_id_by_name(t['MasterName'])

            # 检查高手是否在跟踪列表中
            if master_id and master_id in followed_ids:
                # 确保所有必要字段都存在
                required_fields = ['StockCode', 'StockName', 'TradeType', 'TradePrice', 'TradeDate']
                if not all(field in t for field in required_fields):
                    logger.warning(f"跳过无效交易记录: 缺少必要字段: {t}")
                    continue

                # 获取该高手的所有交易记录
                trades_list = self.db_manager.get_trades_by_master(master_id)

                # 查找匹配的交易记录
                trade_id = None
                for trade_record in trades_list:
                    # 确保trade_record中包含所需字段
                    if ('StockCode' in trade_record and 'TradeType' in trade_record and
                            'TradePrice' in trade_record and 'TradeDate' in trade_record):
                        # 比较关键字段
                        if (trade_record['StockCode'] == t['StockCode'] and
                                trade_record['TradeType'] == t['TradeType'] and
                                trade_record['TradePrice'] == t['TradePrice'] and
                                datetime.fromisoformat(trade_record['TradeDate']) == t['TradeDate']):
                            trade_id = trade_record['TradeID']
                            break
                    else:
                        logger.warning(f"数据库中的交易记录格式无效: {trade_record}")

                # 如果找到匹配的交易记录，添加TradeID
                if trade_id:
                    t['TradeID'] = trade_id
                    monitored_trades.append(t)
                else:
                    logger.warning(f"无法找到交易记录ID: {t['MasterName']} - {t['StockName']} ({t['TradeType']})")

        logger.info(f"发现 {len(monitored_trades)} 条跟踪高手的新交易")

        # 模拟跟单
        alert_messages = []  # 存储所有跟单信息
        follow_count = 0  # 跟单计数器
        for trade in monitored_trades:
            follow_count += 1

            # 检查是否已跟单
            if self.db_manager.is_trade_copied(trade['TradeID']):
                logger.info(f"跳过已跟单交易: {trade['MasterName']} - {trade['StockName']} ({trade['TradeType']})")
                continue

            # 模拟交易
            sim_result = self.simulator.simulate_trade(trade)

            # 保存模拟交易
            self.db_manager.add_simulated_trade(
                trade['TradeID'],
                sim_result['SimPrice'],
                sim_result['SimVolume'],
                sim_result['SimResult'],
                sim_result['ProfitLoss'],
                sim_result['Profitsyje']
            )

            # 创建跟单记录
            trade_record = {
                "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "master": trade['MasterName'],
                "stockcode": trade['StockCode'],
                "stockname": trade['StockName'],
                "operation": trade['TradeType'],
                "price": sim_result['SimPrice'],
                "volume": sim_result['SimVolume'],
                "status": sim_result['SimResult'],
                "Profitsyje": sim_result['Profitsyje']
            }

            # 添加到监控记录
            self.add_monitor_record(trade_record)

            # 构建跟单信息
            alert_message = (
                f"【跟单第 ({follow_count}) 条】\n"
                f"高手: {trade['MasterName']}\n"
                f"股票: {trade['StockName']}({trade['StockCode']})\n"
                f"交易类型: {trade['TradeType']}\n"
                f"价格: {trade['TradePrice']} 数量: {trade['TradeVolume']}\n"
                f"模拟结果: {sim_result['SimResult']}\n"
                f"盈亏: {sim_result['ProfitLoss']:.2f}元\n"
                f"剩余资金: {sim_result['Profitsyje']:.2f}元"
            )

            alert_messages.append(alert_message)

            # 播放声音提醒
            winsound.Beep(1000, 500)  # 1000Hz, 500ms

        # 显示跟单汇总信息
        if alert_messages:
            separator = "\n" + "=" * 60 + "\n"
            final_output = separator.join(alert_messages)

            self.log_message.emit("\n" + "*" * 70, "INFO")
            self.log_message.emit("跟单完成汇总信息:", "INFO")
            self.log_message.emit("*" * 70, "INFO")
            self.log_message.emit(final_output, "INFO")
            self.log_message.emit("*" * 70, "INFO")

    def add_monitor_record(self, record):
        """添加监控记录"""
        self.monitor_trades.append(record)

        # 发出新交易信号
        self.new_trade_found.emit(record)